namespace Easydp.Security
{
    using System;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Security.Permissions;
    using System.Text.RegularExpressions;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
   
    public class ViewHelper
    {
        
        public static object CreateSettingsFrom(GridView view)
        {
            if (view == null)
                return null;
            return new Triplet(view.SelectedValue, new Pair(view.SortExpression, view.SortDirection), new Pair(view.PageIndex, view.SelectedIndex));
        }
        
        public static object ApplySettingsTo(GridView view, object settings)
        {
            if (view.Page.IsPostBack)
                return null;
            try
            {
                Triplet t = ((Triplet)(settings));
                Pair sorting = ((Pair)(t.Second));
                view.Sort(((string)(sorting.First)), ((SortDirection)(Convert.ChangeType(sorting.Second, typeof(SortDirection)))));
                Pair position = ((Pair)(t.Third));
                view.PageIndex = ((int)(position.First));
                view.SelectedIndex = ((int)(position.Second));
                return t.First;
            }
            catch (Exception )
            {
                return null;
            }
        }
        
        public static void DecorateRow(GridView view, GridViewRow row)
        {
            if (row.RowType == DataControlRowType.Header)
            {
                if (String.IsNullOrEmpty(view.SortExpression))
                    return;
                LiteralControl sortIndicator = new LiteralControl(String.Format("<img src=\"{0}/{1}/Sort{2}.gif\" align=\"absmiddle\"/>", view.ResolveClientUrl("~/App_Themes"), view.Page.Theme, view.SortDirection));
                for (int i = 0; i < view.Columns.Count; i++)
                    if (view.Columns[i].SortExpression == view.SortExpression)
                    {
                        row.Cells[i].Controls.AddAt(0, sortIndicator);
                        return;
                    }
            }
            if (row.RowType == DataControlRowType.DataRow)
                for (int i = 0; i < view.Columns.Count; i++)
                    if (view.Columns[i].Visible)
                        DecorateButtons(row.Cells[i].Controls, view);
        }
        
        public static void DecorateItem(DetailsView view)
        {
            foreach (DetailsViewRow row in view.Rows)
            {
                if (row.RowType == DataControlRowType.DataRow)
                {
                    foreach (TableCell cell in row.Cells)
                    {
                        DecorateButtons(cell.Controls, view);
                    }
                }
            }
        }
        
        public static void DecorateButtons(ControlCollection controls, DataBoundControl view)
        {
            foreach (Control c in controls)
            {
                if (c is IButtonControl)
                {
                    IButtonControl button = ((IButtonControl)(c));
                    if (button.CommandName == "Delete")
                        ((WebControl)(c)).Attributes["onclick"] = "if(!confirm(\'Delete?\'))return false;";
                    if (!IsCommandAllowed(view, button.CommandName))
                        c.Visible = false;
                }
                else
                    DecorateButtons(c.Controls, view);
            }
        }
        
        public static bool IsCommandAllowed(DataBoundControl view, string commandName)
        {
            ObjectDataSource ds = ((ObjectDataSource)(view.NamingContainer.FindControl(view.DataSourceID)));
            if ((ds != null && !String.IsNullOrEmpty(ds.TypeName)))
            {
                SortedDictionary<string, List<string>> commandRoles = ((SortedDictionary<string, List<string>>)(HttpContext.Current.Cache["Web.ViewHelper." + ds.TypeName]));
                if (commandRoles == null)
                {
                    Type t = Type.GetType(ds.TypeName);
                    commandRoles = new SortedDictionary<string, List<string>>();
                    MethodInfo[] methods = t.GetMethods();
                    foreach (MemberInfo method in methods)
                    {
                        object[] rolePermissions = method.GetCustomAttributes(typeof(PrincipalPermissionAttribute), true);
                        if (rolePermissions.Length > 0)
                        {
                            object[] attributes = method.GetCustomAttributes(typeof(DataObjectMethodAttribute), true);
                            if (attributes.Length > 0)
                            {
                                DataObjectMethodType methodType = ((DataObjectMethodAttribute)(attributes[0])).MethodType;
                                List<string> roles = new List<string>();
                                if (methodType == DataObjectMethodType.Delete)
                                    commandRoles.Add("Delete", roles);
                                else
                                    if (methodType == DataObjectMethodType.Update)
                                    {
                                        commandRoles.Add("Edit", roles);
                                        commandRoles.Add("Update", roles);
                                    }
                                    else
                                        if (methodType == DataObjectMethodType.Insert)
                                        {
                                            commandRoles.Add("New", roles);
                                            commandRoles.Add("Insert", roles);
                                        }
                                foreach (PrincipalPermissionAttribute permission in rolePermissions)
                                {
                                    if (permission.Action == SecurityAction.Demand)
                                        roles.Add(permission.Role);
                                }
                            }
                        }
                    }
                    HttpContext.Current.Cache["Web.ViewHelper." + ds.TypeName] = commandRoles;
                }
                if (commandRoles.ContainsKey(commandName))
                {
                    foreach (string role in commandRoles[commandName])
                    {
                        if (HttpContext.Current.User.IsInRole(role))
                            return true;
                    }
                    return false;
                }
            }
            return true;
        }
        
        public static bool SelectMenuItemByUrlReferrer(Menu tabs)
        {
            if (HttpContext.Current.Request.UrlReferrer == null)
                return false;
            Match m = Regex.Match(HttpContext.Current.Request.UrlReferrer.ToString(), "(New)*(\\w+).aspx");
            if (m.Success)
            {
                MenuItemCollection items = tabs.Items;
                if ((items.Count > 0 && items[0].ChildItems.Count > 0))
                    items = items[0].ChildItems;
                foreach (MenuItem item in items)
                {
                    if ((Regex.IsMatch(item.Value, m.Groups[2].Value) || Regex.IsMatch(item.Text.Replace(" ", ""), m.Groups[2].Value)))
                    {
                        item.Selected = true;
                        return true;
                    }
                }
            }
            return false;
        }
        
        public static void EnableMenusInUpdatePanel()
        {
            Page currentPage = ((Page)(HttpContext.Current.CurrentHandler));
            if (currentPage != null)
            {
                currentPage.ClientScript.RegisterClientScriptInclude(typeof(ViewHelper), "Ajax.MenuFix.js", currentPage.ResolveClientUrl("~/Scripts/Ajax.MenuFix.js"));
                currentPage.ClientScript.RegisterStartupScript(typeof(ViewHelper), "Ajax_FixMenu", "Ajax_FixMenu();\r\n", true);
            }
        }
    }
}
